package com.szeastroc.common.utils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.codec.Base64;

public class TextUtil {
private static final String PASSWORD_KEY = "2ea5f&#2asf!1";
    
    static final String CHARTS = "abcdefghijklmnopqrstuvwxyz012346789";
    static final int CHARTS_LENGTH = CHARTS.length();
    
    public static String generateCode() {
        String randomChar = String.valueOf(CHARTS.charAt(new Random().nextInt(CHARTS_LENGTH)));
        String prefix = Long.toString(new Date().getTime(), 36);
        return String.format("%s%s", prefix, randomChar);
    }
    
    private static SecureRandom random = new SecureRandom();
    
    /**
     * 使用SecureRandom随机生成Long. 
     */
    public static double randomLong() {
        return Math.abs(random.nextInt(50));
    }

    /**
     * 说明：Md5加密
     * @author shiw
     *         2014年7月19日
     * @param text
     * @return
     * @throws Exception
     */
    public static String md5(String text) {
        MessageDigest alg = null;
        try {
            alg = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        alg.update(text.getBytes());
        byte[] digesta = alg.digest();
        return byte2Hex(digesta);
    }

    /**
     * 说明：转换成16进制
     * @author shiw
     *         2014年7月19日
     * @param paramArrayOfByte
     * @return
     */
    static String byte2Hex(byte[] buf) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex);
        }
        return sb.toString();
    }

    /**
     * 说明：16进制转BYTE
     * @author shiw
     *         2014年7月19日
     * @param hexStr
     * @return
     */
    public static byte[] hex2byte(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }

    /**
     * 说明：获取AES密码KEY
     * @author shiw
     *         2014年7月19日
     * @return
     * @throws Exception
     */
    private static SecretKeySpec getKey() throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128, new SecureRandom(PASSWORD_KEY.getBytes()));
        SecretKey secretKey = kgen.generateKey();
        byte[] enCodeFormat = secretKey.getEncoded();
        SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
        return key;
    }

    /**
     * 说明：AES加密
     * @author shiw
     *         2014年7月19日
     * @param text
     * @return
     */
    public static String encrypt(String text) {
        String result = "";
        try {
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, getKey());
            byte[] textByte = cipher.doFinal(text.getBytes("UTF-8"));
            result = byte2Hex(textByte);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 说明：AES解密
     * @author shiw
     *         2014年7月19日
     * @param text
     * @return
     */
    public static String decrypt(String text) {
        String result = "";
        try {
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, getKey());
            byte[] textByte = cipher.doFinal(hex2byte(text));
            result = new String(textByte);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 说明：获取UUID
     * @return
     */
    public static synchronized String getUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * 将序号补0至length参数的长度
     * @param serialNo 序号
     * @param length 总长度
     * @return
     */
    public static String appendZero(Long serialNo, int length) {
        String pattern = "%0" + length + "d";
        return String.format(pattern, serialNo);
    }

    
    /**
     * MD5后再base64编码 
     * @param str
     * @return
     */
    public static String md5Base64(String str) {
        String encodeStr = "";
        try {
            byte[] utfBytes = str.getBytes("UTF-8");
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(utfBytes);
            byte[] md5Bytes = mdTemp.digest();
            Base64 base64 = new Base64();
            byte[] base64Bytes = base64.encode(md5Bytes);
            encodeStr = new String(base64Bytes);
        } catch (Exception e) {
            return encodeStr;
        }
        return encodeStr;
    }
    
    public static String randomChar() {
        int start = new Random().nextInt(25);
        char c = (char) (start + 65);
        return String.valueOf(c);
    }
    
    /**
     * 
     * @param nickname
     * @return
     */
    public static String encodingCharset(String nickname) {
        if (StringUtils.isNoneBlank(nickname)) {
            try {
                if (nickname.equals(new String(nickname.getBytes("ISO8859-1"), "ISO8859-1"))) {
                    nickname = new String(nickname.getBytes("ISO8859-1"), "UTF-8");
                }
            } catch (UnsupportedEncodingException ignore) {}
        }
        return nickname;
    }
    
    private static boolean isEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD)
                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                || ((codePoint >= 0x010000) && (codePoint <= 0x10FFFF));
    }

    public static String handleNickName(String nickName) {
        StringBuilder _sb = new StringBuilder();
        int _l = nickName.length();
        for (int i = 0; i < _l; i++) {
            char _s = nickName.charAt(i);
            if (isEmojiCharacter(_s)) {
                _sb.append(_s);
            }
        }
        return _sb.toString();
    }
}
